package com.tsd.jxc.stock.service.impl;

import com.tsd.core.constants.VersionConstants;
import com.tsd.core.thread.ThreadPoolTaskUtil;
import com.tsd.core.utils.DoubleUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.HlpException;
import com.tsd.core.vo.PageBean;
import com.tsd.jxc.buy.entity.JxcBuyOrderExt;
import com.tsd.jxc.buy.entity.JxcBuyReturnBillExt;
import com.tsd.jxc.sale.entity.JxcSaleOrderExt;
import com.tsd.jxc.sale.entity.JxcSaleReturnBillExt;
import com.tsd.jxc.setting.JxcSettingUtil;
import com.tsd.jxc.stock.dao.JxcStockGoodsMapper;
import com.tsd.jxc.stock.dao.JxcStockWarehouseMapper;
import com.tsd.jxc.stock.entity.JxcStockGoods;
import com.tsd.jxc.stock.entity.JxcStockGoodsExt;
import com.tsd.jxc.stock.entity.JxcStockWarehouseExt;
import com.tsd.jxc.stock.service.JxcStockGoodsService;
import com.tsd.jxc.stock.vo.JxcStockGoodsVo;
import com.tsd.jxc.utils.ClothingUtil;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.entity.SysUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述：JxcStockGoods 服务实现层
 *
 * @author Hillpool
 * @date 2022/07/29 15:06:33
 */
@Service
public class JxcStockGoodsServiceImpl extends BaseServiceImpl implements JxcStockGoodsService {

    @Resource
    private JxcStockGoodsMapper jxcStockGoodsMapper;
    @Resource
    private JxcStockWarehouseMapper jxcStockWarehouseMapper;

    @Override
    public JxcStockGoods getJxcStockGoodsById(Long id) throws Exception {
        return jxcStockGoodsMapper.selectByPrimaryKey(id);
    }

    @Override
    public JxcStockGoodsExt queryBySid(String sid) throws Exception {
        return jxcStockGoodsMapper.selectBySid(sid);
    }

    @Override
    public void deleteJxcStockGoodss(List<String> list, SysUser opUser) throws Exception {
        for (String sid : list) {
            JxcStockGoods old = jxcStockGoodsMapper.selectBySid(sid);
            super.checkEmpty(old, "该记录不存在");
            super.autoInjectBaseData(old, opUser, TYPE_DELETE);
            jxcStockGoodsMapper.updateByPrimaryKeySelective(old);
        }
    }

    @Override
    public void saveJxcStockGoods(JxcStockGoods record, SysUser opUser) throws Exception {
        if (HlpUtils.isEmpty(record.getId())) {
            super.autoInjectBaseData(record, opUser, this.TYPE_CREATE);
            jxcStockGoodsMapper.insertSelective(record);
        } else {
            super.autoInjectBaseData(record, opUser, this.TYPE_UPDATE);
            jxcStockGoodsMapper.updateByPrimaryKeySelective(record);
        }
    }

    @Override
    public void initJxcStockGoods(List<String> goods_sid_list, SysUser opUser) throws Exception {
        Map<String, Object> params = new HashMap<>(1);
        params.put("dr", 0);
        List<JxcStockWarehouseExt> warehouseExts = jxcStockWarehouseMapper.selectByParams(params);
        for (JxcStockWarehouseExt w : warehouseExts) {
            for (String goods_sid : goods_sid_list) {
                JxcStockGoodsExt t = new JxcStockGoodsExt();
                t.setGoods_sid(goods_sid);
                t.setWarehouse_sid(w.getSid());
                super.autoInjectBaseData(t, opUser, this.TYPE_CREATE);
                jxcStockGoodsMapper.initData(t);
            }
        }
    }

    @Override
    public List<JxcStockGoodsExt> findJxcStockGoodss(Map<String, Object> params, PageBean page) throws Exception {
        return jxcStockGoodsMapper.selectByPage(params, page);
    }

    @Override
    public List<JxcStockGoodsVo> findJxcStockGoods4Clothing(Map<String, Object> params, PageBean page) throws Exception {
        List<JxcStockGoodsVo> list = jxcStockGoodsMapper.select4ClothingByPage(params, page);
        if (!HlpUtils.isEmptyList(list)) {
            List<String> productList = new ArrayList<>();
            for (JxcStockGoodsVo vo : list) {
                List<String> filterList = null;//ListUtil.filter(vo.getProduct_list(), t -> !productList.contains(t));
                if (!HlpUtils.isEmptyList(filterList)) {
                    productList.addAll(filterList);
                }
            }
            List<String> sizeList = ClothingUtil.getClothing_preset_size_list(JxcSettingUtil.getSettingVo());
            List<JxcStockGoodsExt> stockGoodsExtList = null;//jxcStockGoodsMapper.selectValidByProductList(productList);
            for (JxcStockGoodsVo goodsVo : list) {
                Map<String, String> presetProductMap = goodsVo.getClothing_preset_product_map();
                Map<String, BigDecimal> presetQtyMap = new HashMap<>();
                double totalStockSumQty = 0D;
                for (int i = 0; i < sizeList.size(); i++) {
                    String size = sizeList.get(i);
                    String productSid = presetProductMap.get(size);
                    if (HlpUtils.isEmpty(productSid)) {
                        continue;
                    }
                    List<JxcStockGoodsExt> filterList = null;//ListUtil.filter(stockGoodsExtList, t -> productSid.equals(t.getProduct_sid()));
                    if (HlpUtils.isEmptyList(filterList)) {
                        continue;
                    }
                    double totalSumQty = 0D;
                    for (JxcStockGoodsExt goodsExt : filterList) {
                        totalSumQty = DoubleUtil.add(totalSumQty, goodsExt.getStock_sum_qty());
                        totalStockSumQty = DoubleUtil.add(totalStockSumQty, goodsExt.getStock_sum_qty());
                    }
                    presetQtyMap.put("preset_qty_" + i, BigDecimal.valueOf(totalSumQty));
                }
                goodsVo.setStock_sum_qty(BigDecimal.valueOf(totalStockSumQty));
                goodsVo.setPreset_qty_map(presetQtyMap);
            }
        }
        return list;
    }

    @Override
    public List<JxcStockGoodsExt> findJxcStockGoodss(Map<String, Object> params) throws Exception {
        return jxcStockGoodsMapper.selectByParams(params);
    }

    @Override
    public List<JxcStockGoodsExt> queryByEntity(JxcStockGoodsExt params) {
        return jxcStockGoodsMapper.selectByEntity(params);
    }

    @Override
    public List<JxcStockGoodsExt> getAllGoods(Map<String, Object> params) throws Exception {
        return jxcStockGoodsMapper.getAllGoods(params);
    }

    @Override
    public List<JxcStockGoodsExt> getJxcStockGoodsListByGoodsSid(String goods_sid) {
        return jxcStockGoodsMapper.selectByGoodsSid(goods_sid);
    }

    @Override
    public void batchImportStockGoods(List<JxcStockGoodsVo> list, SysUser opUser) throws Exception {
        List<JxcStockGoodsVo> filters = ListUtil.filter(list, t -> HlpUtils.isEmpty(t.getSid()));
        if (!HlpUtils.isEmptyList(filters)) {
            List<String> indexList = ListUtil.map(filters, JxcStockGoodsVo::getIndex);
            throw new HlpException("序号：" + StringUtils.join(indexList, "、") + " sid为空");
        }
        List<String> sidList = ListUtil.map(list, JxcStockGoodsVo::getSid);
        JxcStockGoodsExt params = new JxcStockGoodsExt();
        params.setDr(0);
        params.setSid_list(sidList);
        List<JxcStockGoodsExt> goodsExtList = jxcStockGoodsMapper.selectByEntity(params);
        if (HlpUtils.isEmptyList(goodsExtList)) {
            return;
        }
        List<JxcStockGoodsExt> updateList = new ArrayList<>();
        for (JxcStockGoodsExt goodsExt : goodsExtList) {
            JxcStockGoodsVo goodsVo = ListUtil.get(list, t -> goodsExt.getSid().equals(t.getSid()));
            if (goodsVo == null) {
                continue;
            }
            // 检查导入后库存数量是否小于0
            double saleQty = DoubleUtil.add(goodsExt.getInit_qty(), goodsExt.getTotal_in_qty());
            saleQty = DoubleUtil.sub(saleQty, goodsExt.getStock_sum_qty());
            double stockSumQty = DoubleUtil.add(goodsVo.getInit_qty(), goodsExt.getTotal_in_qty());
            stockSumQty = DoubleUtil.sub(stockSumQty, saleQty);
            if (stockSumQty < 0) {
                throw new HlpException("序号：" + goodsVo.getIndex() + " 导入后剩余库存数量小于0，无法导入！");
            }
            double saleAmount = DoubleUtil.add(goodsExt.getInit_amount(), goodsExt.getTotal_in_amount());
            saleAmount = DoubleUtil.sub(saleAmount, goodsExt.getStock_sum_amount());
            double stockSumAmount = DoubleUtil.add(goodsVo.getInit_amount(), goodsExt.getTotal_in_amount());
            stockSumAmount = DoubleUtil.sub(stockSumAmount, saleAmount);
            super.autoInjectBaseData(goodsExt, opUser, TYPE_UPDATE);
            goodsExt.setStock_sum_qty(BigDecimal.valueOf(stockSumQty));
            goodsExt.setStock_sum_amount(BigDecimal.valueOf(stockSumAmount));
            goodsExt.setInit_qty(goodsVo.getInit_qty());
            goodsExt.setInit_amount(goodsVo.getInit_amount());
            double totalInQty = DoubleUtil.add(goodsVo.getInit_qty(), goodsExt.getTotal_in_qty());
            double totalInAmount = DoubleUtil.add(goodsVo.getInit_amount(), goodsExt.getTotal_in_amount());
            goodsExt.setAvg_cost(BigDecimal.valueOf(DoubleUtil.div(totalInAmount, totalInQty, 4)));
            updateList.add(goodsExt);
        }
        if (!HlpUtils.isEmptyList(updateList)) {
            ThreadPoolTaskUtil.executeInList(updateList, false, item -> jxcStockGoodsMapper.updateByPrimaryKeySelective(item));
        }
    }

    @Override
    public void updateJxcStockGoodss(List<Map> data, SysUser opUser) throws Exception {
        for (Map map : data) {
            JxcStockGoodsExt old = jxcStockGoodsMapper.selectBySid(map.get("stock_goods_sid").toString());
            super.checkEmpty(old, "该记录不存在");
            super.autoInjectBaseData(old, opUser, TYPE_UPDATE);
            old.setStock_sum_qty(BigDecimal.valueOf(HlpUtils.getDouble(map, "check_qty")));
            jxcStockGoodsMapper.updateByPrimaryKeySelective(old);
        }
    }

    @Override
    public void updateBySaleOrder(int addOrSub, JxcSaleOrderExt saleOrderExt) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("sid", saleOrderExt.getSid());
        map.put("op", addOrSub);
        jxcStockGoodsMapper.updateBySaleOrder(map);
    }

    @Override
    public void updateBySaleReturnBill(int addOrSub, JxcSaleReturnBillExt returnBillExt) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("sid", returnBillExt.getSid());
        map.put("op", addOrSub);
        jxcStockGoodsMapper.updateBySaleReturnBill(map);
    }

    @Override
    public void updateByBuyOrder(int addOrSub, JxcBuyOrderExt buyOrderExt) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("sid", buyOrderExt.getSid());
        map.put("op", addOrSub);
        if (VersionConstants.accountSetVersionIsFree()) {
            map.put("is_free", 1);
        }
        jxcStockGoodsMapper.updateByBuyOrder(map);
    }

    @Override
    public void updateByBuyReturnBill(int addOrSub, JxcBuyReturnBillExt returnBillExt) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("sid", returnBillExt.getSid());
        map.put("op", addOrSub);
        if (VersionConstants.accountSetVersionIsFree()) {
            map.put("is_free", 1);
        }
        jxcStockGoodsMapper.updateByBuyReturnBill(map);
    }
}
